# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.

# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.

import math
import torch
from torchvision import transforms
from torchvision.transforms import functional as F


class RandomResizedCrop(transforms.RandomResizedCrop):
    """
    这段代码使用的原因是一开始是用tf进行的，为了方便和torch的代码进行对齐
    随机选择裁剪区域的位置和大小增强数据的多样性，确保裁剪后的图像满足特定的面积和宽高比的要求
    RandomResizedCrop for matching TF/TPU implementation: no for-loop is used.
    This may lead to results different with torchvision's version.
    Following BYOL's TF code:
    https://github.com/deepmind/deepmind-research/blob/master/byol/utils/dataset.py#L206
    """

    # scale是裁剪图像相对于原始图像面积的比例范围，ratio是裁剪图像的宽高比的范围
    @staticmethod
    def get_params(img, scale, ratio):
        width, height = F._get_image_size(img)  # 获取原始图像的宽和高
        area = height * width  # 获取原始图像数据的面积
        # 根据目标面积和宽高比计算出裁剪图像的宽度和高度
        target_area = area * torch.empty(1).uniform_(scale[0], scale[1]).item()
        log_ratio = torch.log(torch.tensor(ratio))  # 返回log为底的自然对数？ 取完对数再exp回去？
        aspect_ratio = torch.exp(
            torch.empty(1).uniform_(log_ratio[0], log_ratio[1])
        ).item()

        w = int(round(math.sqrt(target_area * aspect_ratio)))
        h = int(round(math.sqrt(target_area / aspect_ratio)))
        # 确保裁剪之后的图像位于原始图像的内部
        w = min(w, width)
        h = min(h, height)
        # 返回裁剪之后图像的左上角的坐标以及宽和高 先算宽和高，然后确定左上角波动的范围
        i = torch.randint(0, height - h + 1, size=(1,)).item()
        j = torch.randint(0, width - w + 1, size=(1,)).item()

        return i, j, h, w
